Project Detail

Professional Portfolio Site

This is the portfolio you're looking at right now — built entirely in Flask, backed by PostgreSQL, and deployed on Railway with a custom domain. It's not a template or a no-code builder; it's a real web application designed and built from scratch.

The whole thing is maintained through a custom admin dashboard — adding or updating projects never means touching the codebase. Project images are stored on Cloudflare R2 and backed up to GitHub. An AI assistant powered by RAG answers questions about the portfolio using LangChain, ChromaDB, and Groq. It's the kind of system I'd build professionally — and that's exactly the point.

Web web-app python REST-API authentication CRUD deployment flask admin-dashboard CI-CD RAG LLM

Quick Facts

Tech:
Python Flask SQLAlchemy PostgreSQL SQLite Bootstrap Jinja2 Flask-WTF Gunicorn Docker pytest GitHub Actions Railway Cloudflare R2 boto3 LangChain ChromaDB Groq sentence-transformers Resend flask-limiter

Overview

Problem

Most developer portfolios are static HTML pages thrown together with a CSS template. That gets the job done, but it doesn't actually demonstrate anything about how the developer writes software. I wanted my portfolio to be the proof of skill, not just a holder for links to other projects. Beyond that, maintaining a static site gets tedious fast — every update means editing HTML by hand, pushing manually, and hoping nothing breaks. I needed something I could actually run like a real product.

Solution

I built a full-stack Flask application structured around four blueprints: public routes, an admin blueprint, a REST API, and an AI assistant. All project data lives in PostgreSQL via SQLAlchemy. The admin dashboard handles full CRUD on projects, media uploads to Cloudflare R2, tag management, contact messages, and automated JSON backups before every write. A GitHub Actions CI/CD pipeline runs the full test suite on every push and deploys to Railway via railway up only when tests pass. The AI assistant uses RAG — LangChain, ChromaDB, and local sentence-transformers embeddings — to answer questions about the portfolio, with Groq's Llama 3 as the LLM.

Challenges

Making the snapshot sync genuinely reliable was the hardest part — early on, deleting a project on the live site wouldn't stick because the sync only ever upserted and never deleted. I had to redesign it as authoritative: any project not in the snapshot gets removed on startup. Getting the deploy pipeline stable took several iterations: Railway token naming, GitHub Actions path filters, and Railway's own auto-deploy interacting with the Actions workflow all needed untangling. Later, migrating media to Cloudflare R2 introduced its own challenge — the repo's 430+ tracked images exceeded Railway's upload size limit, requiring a full R2 migration and a .railwayignore strategy to keep deploy payloads small while keeping GitHub as a permanent backup.

Results / Metrics

The portfolio is live at xavieroc.dev and demonstrates the full stack worked through during 100 Days of Code — Flask, SQLAlchemy, REST API design, admin tooling, RAG pipelines, media management with Cloudflare R2, testing with pytest, and deployment with Docker and Railway. The AI assistant answers real questions about the projects using a vector store built from the portfolio data. Building the admin dashboard from scratch instead of reaching for Flask-Admin forced implementation of auth, CSRF protection, file handling, and backup logic — which is where the real learning happened.

Screenshots

Click to enlarge.

Click to enlarge.

Videos

No videos available yet.